﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using Microsoft.Win32;
using System.Drawing.Imaging;

namespace Tools.Helper
{
    /// <summary>  
    /// 获取指定文件的Icon图像getIcon()、getIcon2()  
    /// </summary>  
    public class FileIcon
    {
        public static Icon GetIco(string fileName)
        {
            if (fileName.EndsWith(".lnk"))
            {
                IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
                IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(fileName);
                fileName = shortcut.TargetPath;
            }
            //选中文件中的图标总数
            var iconTotalCount = PrivateExtractIcons(fileName, 0, 0, 0, null, null, 0, 0);

            //用于接收获取到的图标指针
            IntPtr[] hIcons = new IntPtr[iconTotalCount];
            //对应的图标id
            int[] ids = new int[iconTotalCount];
            PrivateExtractIcons(fileName, 0, 256, 256, hIcons, ids, iconTotalCount, 0);
            if (fileName.EndsWith(".exe"))
            {
                try
                {
                    return Icon.FromHandle(hIcons[0]);
                }
                catch (Exception)
                {

                }
            }
            try
            {
                return Icon.ExtractAssociatedIcon(fileName);
            }
            catch (Exception)
            {
                return global::Tools.Properties.Resources.delete;
            }             
        }



        //details: https://msdn.microsoft.com/en-us/library/windows/desktop/ms648075(v=vs.85).aspx
        //Creates an array of handles to icons that are extracted from a specified file.
        //This function extracts from executable (.exe), DLL (.dll), icon (.ico), cursor (.cur), animated cursor (.ani), and bitmap (.bmp) files. 
        //Extractions from Windows 3.x 16-bit executables (.exe or .dll) are also supported.
        [DllImport("User32.dll")]
        public static extern int PrivateExtractIcons(
            string lpszFile, //file name
            int nIconIndex,  //The zero-based index of the first icon to extract.
            int cxIcon,      //The horizontal icon size wanted.
            int cyIcon,      //The vertical icon size wanted.
            IntPtr[] phicon, //(out) A pointer to the returned array of icon handles.
            int[] piconid,   //(out) A pointer to a returned resource identifier.
            int nIcons,      //The number of icons to extract from the file. Only valid when *.exe and *.dll
            int flags        //Specifies flags that control this function.
        );

        //details:https://msdn.microsoft.com/en-us/library/windows/desktop/ms648063(v=vs.85).aspx
        //Destroys an icon and frees any memory the icon occupied.
        [DllImport("User32.dll")]
        public static extern bool DestroyIcon(
            IntPtr hIcon //A handle to the icon to be destroyed. The icon must not be in use.
        );
    }
}


